/* Copyright 2001,2002,2003 NAH6
 * All Rights Reserved
 *
 * Parts Copyright DoD, Parts Copyright Starium
 *
 */
          /*LINTLIBRARY*/
          /*PROTOLIB1*/
#include <math.h>
#include "main.h"
#include "scb_code.h"

/**************************************************************************
*
* ROUTINE
*		SCBGainEncode
*
* FUNCTION
*
*		encode and quantize code book gain
*
* SYNOPSIS
*		SCBGainEncode(UGain, QGain)
*
*   formal
*
*                       data    I/O
*       name            type    type    function
*       -------------------------------------------------------------------
*	UGain		float	i	code book gain input (true value)
*	QGain		int	o	encoded code book gain ZERO BASED index
*
*	SCBGainEncode	float	func	encoded code book gain
*
***************************************************************************
*
* DESCRIPTION
**
*      Fast code book gain quantizer to allow practical quantization
*      inside the code book search loop. A binary tree search quantization 
*      is implemented below.
*
**************************************************************************/
 
/* *Log quantization                               */

static float SCBGainTable[32] =
{
 -1330., -870., -660., -520., -418., -340., -278., -224.,
 -178., -136.,  -98.,  -64.,  -35.,  -13.,   -3.,   -1.,
    1.,    3.,   13.,   35.,   64.,   98.,  136.,  178.,
  224.,  278.,  340.,  418.,  520.,  660.,  870., 1330.
};

float SCBGainEncode(
float 	UGain,
int 	*QGain)

{
  int i;
  static float midpoints[31] = 
  {
    -1100., -765., -590., -469., -379., -309., -251., -201.,
     -157., -117.,  -81.,  -49.5, -24.,   -8.,   -2.,    0.,
        2.,    8.,   24.,   49.5,  81.,  117.,  157.,  201.,
      251.,  309.,  379.,  469.,  590.,  765., 1100.
  };

  /* *Binary tree search for closest gain				 */

  for (*QGain = 15, i = 8; i >= 1; i = i >> 1)
  {
    if (UGain > midpoints[*QGain])
      *QGain += i;
    else
      *QGain -= i;
  }
  if (UGain > midpoints[*QGain])
    (*QGain)++;

  /* *Return quantized gain and ZERO based index			 */

  return (SCBGainTable[*QGain]);
}
   

/*

*************************************************************************
*
* ROUTINE
*		SCBGainDecode
*
* FUNCTION
*
*		decode code book gain from the quantized gain 
*
* SYNOPSIS
*		SCBGainDecode(QGain, UGain)
*
*   formal
*
*                       data    I/O
*       name            type    type    function
*       -------------------------------------------------------------------
*	QGain		int	i	Quantized gain
*	UGain		float	o	Unquantized gain
*
***************************************************************************
*
* REFERENCES
*
*       Quantizing for Minimum Distorion
*       J. Max
*       IRE Trans. Inform. Theory, vol. IT-6, pp.7-12, Mar. 1960
*
***************************************************************************
*
*       The data used in the table generation is from 3m3f.spd.
*
**************************************************************************/
void SCBGainDecode(
int 	QGain, 
float 	*UGain)

{
  /* Choose appropriate gain                                         */

    *UGain = SCBGainTable[QGain];

}
